package com.sdwl.brcl.util;

import cn.hutool.core.bean.BeanUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.BeanWrapper;
import org.springframework.beans.BeanWrapperImpl;

import java.util.*;

/**
 *  copy两个对象的属性
 * @author xied
 * @date 2021/11/3 13:46
 */
@Slf4j
public class CopyUtils extends BeanUtil {

    /**在做项目时遇到需要copy两个对象之间的属性值，
     * 但是有源对象有null值，在使用BeanUtils来copy时null值会覆盖目标对象的同名字段属性值，
     * 然后采用以下方法找到null值字段，然后忽略：*/
    public static String[] getNullPropertyNames (Object source) {
        final BeanWrapper src = new BeanWrapperImpl(source);
        java.beans.PropertyDescriptor[] pds = src.getPropertyDescriptors();

        Set<String> emptyNames = new HashSet<String>();
        for(java.beans.PropertyDescriptor pd : pds) {
            Object srcValue = src.getPropertyValue(pd.getName());
            if (srcValue == null||"".equals(srcValue)){ emptyNames.add(pd.getName());}
        }
        String[] result = new String[emptyNames.size()];
        return emptyNames.toArray(result);
    }

    public static void copyPropertiesIgnoreNull(Object src, Object target){
        BeanUtils.copyProperties(src, target, getNullPropertyNames(src));
    }

    /**
     * 对象拷贝
     * @param source
     * @param target
     * @param <T>
     * @return
     */
    public static <T> T sourceToTarget(Object source, Class<T> target) {
        if (source == null) {
            return null;
        } else {
            T targetObject = null;

            try {
                targetObject = target.newInstance();
                BeanUtils.copyProperties(source, targetObject);
            } catch (Exception e) {
                log.error("convert error ", e);
            }

            return targetObject;
        }
    }

    /**
     * 集合拷贝
     * @param sourceList
     * @param target
     * @param <T>
     * @return
     */
    public static <T> List<T> sourceToTarget(Collection<?> sourceList, Class<T> target) {
        if (sourceList == null) {
            return null;
        } else {
            ArrayList targetList = new ArrayList(sourceList.size());

            try {
                Iterator iterator = sourceList.iterator();

                while(iterator.hasNext()) {
                    Object source = iterator.next();
                    T targetObject = target.newInstance();
                    BeanUtils.copyProperties(source, targetObject);
                    targetList.add(targetObject);
                }
            } catch (Exception e) {
                log.error("convert error ", e);
            }

            return targetList;
        }
    }
}

